iT邦幫忙

2023 iThome 鐵人賽

DAY 4
1

Spike

Spike 是RISC-V官方所推出的ISS (ISA Simulator),以C++所寫成,Spike作為ISA Simulator,為前文所提到的Functional Simulator,注重在行為的正確性,所以不具備統計執行時間等特性,但由於是RISC-V官方所提供的模擬器,且執行速度可達約每秒100MIPS (每秒可執行億個指令),因此常常作為"標準答案"來使用,在製作模擬器時可確認行為是否與Spike結果相同。

如何使用Spike

在開始講Spike之前,我們要先準備一支RISC-V指令編出來的程式才行,俗話說巧婦難為無米之炊,我們在準備好模擬器前需要有一個可以讓他跑的程式,但除非我們的環境本身就是RISC-V的架構否則是沒有辦法直接產生RISC-V的程式的,因此我們會需要先安裝RISC-V官方的toolchain,他可以讓我們在例如x86的電腦編出RISC-V的指令,可以選擇直接去這裡下載官方編好的工具鏈,又或者可以自己從原始碼開始編譯,這部分可以參考高魁良大大的 "與妖精共舞:在 RISC-V 架構上使用 GO 語言實作 binutils 工具包系列 第 2 篇"有非常詳盡的教學,安裝好之後直接寫一個HelloWorld並編譯即可。

riscv64-unknown-elf-gcc -o hello_world.elf main.c

準備好要執行的程式,那我們可以開始編譯Spike了。Spike的編譯過程很簡單,唯一要注意的是Spike本身會使用的device-tree-compiler(dtc)的功能,因此也要先安裝dtc。(關於dtc在後面的章節會再說明)

    
# install dtc
sudo apt install device-tree-compiler 
git  clone https://github.com/riscv-software-src/riscv-isa-sim.git
cd  riscv-isa-sim
# check out to v1.1.0 (last release ver.)
git checkout v1.1.0 
mkdir build
cd build
../configure
make -j 

編好了Spike,那我們接下來就可以開始執行RISC-V的程式啦,不過此時我們開心的./spike hello_wrold.elf,卻發現沒有辦法順利執行,這是為什麼呢!?

PK (Proxy kernel)

Spike有一個配套的假kernel叫做PK,他的主要目的是幫忙Spike在沒有真正的OS(例如linux)的環境下去做一切Linux該做的事情,因此如果沒有PK的話例如semi-hosting (簡單來說就是開讀檔、印出文字到螢幕上)或者是虛擬記憶體的配置等事情都沒有辦法進行,看到這裡大家應該就明白為什麼沒有辦法順利執行HelloWorld了吧。那假設不想要印東西,只想要讓Spike跑一個baremetal的程式可以嗎,理論上是可以的,但是因為Spike會在程式開始跑之前安插一小段ROM code,這裡推測是為了模擬真實的硬體的開機流程 (關於linux開機流程可以參考這個影片)

sim.cc
...
..
 start_pc = start_pc == reg_t(-1) ? get_entry_point() : start_pc;

  uint32_t reset_vec[reset_vec_size] = {
    0x297,                                      // auipc  t0,0x0
    0x28593 + (reset_vec_size * 4 << 20),       // addi   a1, t0, &dtb
    0xf1402573,                                 // csrr   a0, mhartid
    get_core(0)->get_xlen() == 32 ?
      0x0182a283u :                             // lw     t0,24(t0)
      0x0182b283u,                              // ld     t0,24(t0)
    0x28067,                                    // jr     t0
    0,
    (uint32_t) (start_pc & 0xffffffff),
    (uint32_t) (start_pc >> 32)
  };

這段程式碼會將dtb (前面提到dtc的產物的位置儲存在a1,將目前的cpu編號存在a0後跳到預設的pc位置,這裡是設定為0x80000000),因此除非我們特別去修改spike的rom段,又或者是我們執行的程式的entry point恰好是0x80000000,否則是沒有辦法正常執行的。

我們可以走正規的方法,使用pk來執行該程式,pk的安裝方法與Spike相當接近,流程如下。

git clone https://github.com/riscv/riscv-pk.git
cd riscv-pk
mkdir build
cd build
#prefix設定安裝路徑,host決定使用的toolchain
../configure --prefix=$RISCV --host=riscv64-unknown-elf
make
make install

之後我們只透過Spike執行pk,並將欲執行的程式作為pk的參數即可正常執行。

./spike /path/to/pk hello_world.elf
>HelloWorld 

這裡有一個可以注意的地方,那就是pk在編譯的時候會需要使用risc-v的toolchain,但Spike卻不用,這是因為Spike是作為一支x86(或任何原生架構)上面的程式,而PK則是執行在Spike上面的risc-v程式。

以上大概就是Spike的基本介紹及使用,其實Spike還有一些蠻不錯的功能,例如log或者是debug模式等,這部份等後續有使用到的時候再帶著大家操作~


碎碎念:Spike應該是大部分接觸risc-v的人會先碰過的工具吧,我也趁這個機會複習了一下Spike的使用方法,明天來試著聊聊看QEMU


上一篇
Day 3 - 處理器的模擬器
下一篇
Day 5 QEMU-功能強大且快速的仿真器
系列文
從零開始的RISC-V ISA Simulator (Another Little RISC-V ISA Simulator)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
高魁良
iT邦新手 1 級 ‧ 2023-09-20 09:54:10

推推!

yoga57894 iT邦新手 5 級 ‧ 2023-09-20 19:19:38 檢舉

謝推XD 大大的文章在我第一次試著Spike/Gem5開Linux的時候幫助很大,藉這個機會感謝大大

我要留言

立即登入留言